package cn.itsource.service.remote;

import cn.itsource.admin.dto.CancelAndComplaintDto;
import cn.itsource.admin.dto.RuleDto;
import cn.itsource.api.DriverRemoteApi;
import cn.itsource.api.RuleFeignClient;
import cn.itsource.constants.RConst;
import cn.itsource.mapper.*;
import cn.itsource.pojo.domain.*;
import cn.itsource.result.JSONResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@RestController
public class RuleFeignClientImpl implements RuleFeignClient {

    @Autowired
    private ChargeRuleStartMapper chargeRuleStartMapper;

    @Autowired
    private ChargeRuleReturnMapper chargeRuleReturnMapper;

    @Autowired
    private ChargeRuleWaitMapper chargeRuleWaitMapper;

    @Autowired
    private DriverRemoteApi driverRemoteApi;

    @Autowired
    private ProfitsharingRuleBaseMapper profitsharingRuleBaseMapper;

    @Autowired
    private ProfitsharingRuleDeductCancelMapper profitsharingRuleDeductCancelMapper;

    @Autowired
    private ProfitsharingRuleDeductComplaintMapper profitsharingRuleDeductComplaintMapper;


    @Override
    public JSONResult valuation(String mileage) {
        // 开始时间
        int hour = LocalDateTime.now().getHour();
        //得到规则
        ChargeRuleStart chargeRuleStart = chargeRuleStartMapper.selectOne(new LambdaQueryWrapper<ChargeRuleStart>()
                .le(ChargeRuleStart::getHourStart, hour)
                .ge(ChargeRuleStart::getHourEnd, hour));
        // 起步公里
        BigDecimal baseMileage = chargeRuleStart.getBaseMileage();
        // 和传过来的预计公里数对比
        /**
         * compareTo
         * 如果返回值为负数，表示第一个对象小于第二个对象；
         * 如果返回值为零，则两个对象相等；
         * 如果返回值为正数，则表示第一个对象大于第二个对象
         */
        BigDecimal mileageBig = new BigDecimal(mileage);
        int i = baseMileage.compareTo(mileageBig);
        //起步公里数大于预计公里数时，就返回起步价
        if (i >= RConst.Num.INT_0) {
            return JSONResult.success(chargeRuleStart.getAmount()); //
        } else { //预计公里数大于基础公里数，会有超出价
            // 多出的公里数 subtract减法
            BigDecimal exceedingMileage = mileageBig.subtract(baseMileage);
            // 额外的钱
            BigDecimal extraMoney = exceedingMileage.multiply(chargeRuleStart.getExceedEveryKmAmount());
            // 总金额
            BigDecimal totalAmount = extraMoney
                    .add(chargeRuleStart.getAmount()) //加超出里程的钱
                    .add(returnJourney(mileageBig)); // 加返程的钱
            return JSONResult.success(totalAmount);
        }
    }

    /**
     * 根据开始时间，获取账单的初始化数据
     * @param hours
     * @return
     */
    @Override
    public JSONResult getRuleDto(int hours) {
        //创建对象
        RuleDto ruleDto = new RuleDto();
        //开始里程
        ChargeRuleStart chargeRuleStart = chargeRuleStartMapper.selectOne(new LambdaQueryWrapper<ChargeRuleStart>()
                .le(ChargeRuleStart::getHourStart, hours)
                .ge(ChargeRuleStart::getHourEnd, hours));

        ruleDto.setBaseMileage(chargeRuleStart.getBaseMileage()); //基础里程
        ruleDto.setBaseMileageAmount(chargeRuleStart.getAmount()); //基础价格
        ruleDto.setExceedBaseMileageEveryKmAmount(chargeRuleStart.getExceedEveryKmAmount()); // 超出价格

        //chargeRuleReturnMapper 只有一天数据
        ChargeRuleReturn chargeRuleReturn = chargeRuleReturnMapper.selectById(RConst.Num.BASE_LONG_1); //查出唯一一条数据
        ruleDto.setFreeBaseReturnMileage(chargeRuleReturn.getFreeBaseReturnMileage()); // 返程里程数
        ruleDto.setExceedBaseReturnEveryKmAmount(chargeRuleReturn.getExceedEveryKmAmount()); //返程价格

        ChargeRuleWait chargeRuleWait = chargeRuleWaitMapper.selectById(RConst.Num.BASE_LONG_1);
        ruleDto.setFreeBaseWaitingMinute(chargeRuleWait.getFreeBaseWaitingMinute()); // 免费等待数
        ruleDto.setExeceedBaseWaitingEveryKmAmount(chargeRuleWait.getExceedEveryMinuteAmount()); //超出等待价格
        return JSONResult.success(ruleDto);

    }

    @Override
    public JSONResult getDriverTotalProportion() {
        //查询司机总投诉和撤单数
        JSONResult cancelAndComplaint = driverRemoteApi.getCancelAndComplaint();
        Object data = cancelAndComplaint.getData();
        // 转为对象
        CancelAndComplaintDto cancelAndComplaintDto = JSONObject.parseObject(JSON.toJSONString(data), CancelAndComplaintDto.class);
        //默认抽成比例
        ProfitsharingRuleBase defaultProportion =
                profitsharingRuleBaseMapper.selectById(RConst.Num.BASE_LONG_1);
        //取消订单的抽成比例
        ProfitsharingRuleDeductCancel cancelProportion = profitsharingRuleDeductCancelMapper.selectOne(
                new LambdaQueryWrapper<ProfitsharingRuleDeductCancel>()
                        .le(ProfitsharingRuleDeductCancel::getNumberFrom, cancelAndComplaintDto.getTotalCancel())
                        .gt(ProfitsharingRuleDeductCancel::getNumberTo, cancelAndComplaintDto.getTotalCancel()));
        //投诉订单的抽成比例
        ProfitsharingRuleDeductComplaint complaintProportion = profitsharingRuleDeductComplaintMapper.selectOne(
                new LambdaQueryWrapper<ProfitsharingRuleDeductComplaint>()
                        .le(ProfitsharingRuleDeductComplaint::getNumberFrom, cancelAndComplaintDto.getTotalComplaint())
                        .gt(ProfitsharingRuleDeductComplaint::getNumberTo, cancelAndComplaintDto.getTotalComplaint()));
        BigDecimal driverTotalProportion = defaultProportion.getDriverRatio();
        if(cancelProportion != null){
            driverTotalProportion =  driverTotalProportion.subtract(cancelProportion.getDriverRatioDeduct());
        }
        if(complaintProportion != null){
            driverTotalProportion =  driverTotalProportion.subtract(complaintProportion.getDriverRatioDeduct());
        }
        //得到司机总的抽成比例
        return JSONResult.success(driverTotalProportion);
    }

    /**
     * 返程费用
     * @param mileageBig
     * @return
     */
    public BigDecimal returnJourney(BigDecimal mileageBig){
        ChargeRuleReturn chargeRuleReturn = chargeRuleReturnMapper.selectById(RConst.Num.BASE_LONG_1);
        BigDecimal freeBaseReturnMileage = chargeRuleReturn.getFreeBaseReturnMileage();
        int i = freeBaseReturnMileage.compareTo(mileageBig);
        if(i >= RConst.Num.INT_0){
            return new BigDecimal(RConst.Num.INT_0);
        }else {
            BigDecimal subtract = mileageBig.subtract(freeBaseReturnMileage);
            BigDecimal multiply = subtract.multiply(chargeRuleReturn.getExceedEveryKmAmount());
            return multiply;
        }
    }
}
